Naučte se efektivně kategorizovat a zpracovávat chyby v React Error Boundaries, čímž zlepšíte stabilitu aplikace a uživatelský prožitek.
Kategorizace chyb v React Error Boundary: Podrobný průvodce
Zpracování chyb je klíčovým aspektem tvorby robustních a udržitelných React aplikací. Zatímco Error Boundaries v Reactu poskytují mechanismus pro elegantní zpracování chyb, které nastanou během vykreslování, pochopení toho, jak kategorizovat a reagovat na různé typy chyb, je zásadní pro vytvoření skutečně odolné aplikace. Tento průvodce prozkoumává různé přístupy ke kategorizaci chyb v rámci Error Boundaries a nabízí praktické příklady a užitečné poznatky pro zlepšení vaší strategie správy chyb.
Co jsou React Error Boundaries?
Error Boundaries, představené v Reactu 16, jsou React komponenty, které zachytávají JavaScriptové chyby kdekoli ve stromu svých podřízených komponent, zaznamenávají tyto chyby a zobrazují záložní UI namísto pádu celého stromu komponent. Fungují podobně jako blok try...catch, ale pro komponenty.
Klíčové vlastnosti Error Boundaries:
- Zpracování chyb na úrovni komponenty: Izolují chyby v rámci specifických podstromů komponent.
- Elegantní degradace: Zabraňují pádu celé aplikace kvůli chybě v jedné komponentě.
- Kontrolované záložní UI: Zobrazují uživatelsky přívětivou zprávu nebo alternativní obsah, když dojde k chybě.
- Logování chyb: Usnadňují sledování a ladění chyb zaznamenáváním informací o chybě.
Proč kategorizovat chyby v Error Boundaries?
Pouhé zachycení chyby nestačí. Efektivní zpracování chyb vyžaduje pochopení toho, co se pokazilo, a odpovídající reakci. Kategorizace chyb v rámci Error Boundaries nabízí několik výhod:
- Cílené zpracování chyb: Různé typy chyb mohou vyžadovat různé reakce. Například síťová chyba může vyžadovat mechanismus opakování, zatímco chyba validace dat může vyžadovat opravu vstupu uživatelem.
- Zlepšený uživatelský prožitek: Zobrazujte informativnější chybové zprávy na základě typu chyby. Obecná zpráva "Něco se pokazilo" je méně užitečná než konkrétní zpráva informující o problému se sítí nebo neplatném vstupu.
- Vylepšené ladění: Kategorizace chyb poskytuje cenný kontext pro ladění a identifikaci hlavní příčiny problémů.
- Proaktivní monitorování: Sledujte frekvenci různých typů chyb, abyste identifikovali opakující se problémy a prioritizovali jejich opravy.
- Strategické záložní UI: Zobrazujte různá záložní UI v závislosti na chybě, čímž uživateli poskytnete relevantnější informace nebo akce.
Přístupy ke kategorizaci chyb
K kategorizaci chyb v rámci React Error Boundaries lze použít několik technik:
1. Použití instanceof
Operátor instanceof kontroluje, zda je objekt instancí konkrétní třídy. To je užitečné pro kategorizaci chyb na základě jejich vestavěných nebo vlastních typů chyb.
Příklad:
class NetworkError extends Error {
constructor(message) {
super(message);
this.name = "NetworkError";
}
}
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
class MyErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null, errorInfo: null };
}
static getDerivedStateFromError(error) {
// Aktualizace stavu, aby další vykreslení zobrazilo záložní UI.
return { hasError: true, error: error };
}
componentDidCatch(error, errorInfo) {
// Chybu můžete také zaznamenat do služby pro hlášení chyb
console.error("Caught error:", error, errorInfo);
this.setState({errorInfo: errorInfo});
}
render() {
if (this.state.hasError) {
// Můžete vykreslit jakékoli vlastní záložní UI
let errorMessage = "Něco se pokazilo.";
if (this.state.error instanceof NetworkError) {
errorMessage = "Došlo k chybě sítě. Zkontrolujte prosím své připojení a zkuste to znovu.";
} else if (this.state.error instanceof ValidationError) {
errorMessage = "Došlo k chybě validace. Zkontrolujte prosím zadané údaje.";
}
return (
<div>
<h2>Chyba!</h2>
<p>{errorMessage}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.toString()}<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
return this.props.children;
}
}
Vysvětlení:
- Jsou definovány vlastní třídy
NetworkErroraValidationError, které rozšiřují vestavěnou tříduError. - V metodě
renderkomponentyMyErrorBoundaryse používá operátorinstanceofke kontrole typu zachycené chyby. - Na základě typu chyby se v záložním UI zobrazí specifická chybová zpráva.
2. Použití chybových kódů nebo vlastností
Dalším přístupem je zahrnout chybové kódy nebo vlastnosti přímo do samotného objektu chyby. To umožňuje jemnější kategorizaci na základě specifických scénářů chyb.
Příklad:
function fetchData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (!response.ok) {
const error = new Error("Network request failed");
error.code = response.status; // Přidání vlastního chybového kódu
reject(error);
}
return response.json();
})
.then(data => resolve(data))
.catch(error => reject(error));
});
}
class MyErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null, errorInfo: null };
}
static getDerivedStateFromError(error) {
// Aktualizace stavu, aby další vykreslení zobrazilo záložní UI.
return { hasError: true, error: error };
}
componentDidCatch(error, errorInfo) {
// Chybu můžete také zaznamenat do služby pro hlášení chyb
console.error("Caught error:", error, errorInfo);
this.setState({errorInfo: errorInfo});
}
render() {
if (this.state.hasError) {
let errorMessage = "Něco se pokazilo.";
if (this.state.error.code === 404) {
errorMessage = "Zdroj nebyl nalezen.";
} else if (this.state.error.code >= 500) {
errorMessage = "Chyba serveru. Zkuste to prosím později znovu.";
}
return (
<div>
<h2>Chyba!</h2>
<p>{errorMessage}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.toString()}<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
return this.props.children;
}
}
Vysvětlení:
- Funkce
fetchDatapřidává do objektu chyby vlastnostcode, která představuje stavový kód HTTP. - Komponenta
MyErrorBoundarykontroluje vlastnostcodek určení specifického scénáře chyby. - Na základě chybového kódu se zobrazují různé chybové zprávy.
3. Použití centralizované mapy chyb
U složitých aplikací může udržování centralizované mapy chyb zlepšit organizaci a udržovatelnost kódu. To zahrnuje vytvoření slovníku nebo objektu, který mapuje typy nebo kódy chyb na specifické chybové zprávy a logiku zpracování.
Příklad:
const errorMap = {
"NETWORK_ERROR": {
message: "Došlo k chybě sítě. Zkontrolujte prosím své připojení.",
retry: true,
},
"INVALID_INPUT": {
message: "Neplatný vstup. Zkontrolujte prosím svá data.",
retry: false,
},
404: {
message: "Zdroj nebyl nalezen.",
retry: false,
},
500: {
message: "Chyba serveru. Zkuste to prosím později znovu.",
retry: true,
},
"DEFAULT": {
message: "Něco se pokazilo.",
retry: false,
},
};
function handleCustomError(errorType) {
const errorDetails = errorMap[errorType] || errorMap["DEFAULT"];
return errorDetails;
}
class MyErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, errorDetails: null, errorInfo: null };
}
static getDerivedStateFromError(error) {
// Aktualizace stavu, aby další vykreslení zobrazilo záložní UI.
const errorDetails = handleCustomError(error.message);
return { hasError: true, errorDetails: errorDetails };
}
componentDidCatch(error, errorInfo) {
// Chybu můžete také zaznamenat do služby pro hlášení chyb
console.error("Caught error:", error, errorInfo);
this.setState({errorInfo: errorInfo});
}
render() {
if (this.state.hasError) {
const { message } = this.state.errorDetails;
return (
<div>
<h2>Chyba!</h2>
<p>{message}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.errorDetails.message}<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
return this.props.children;
}
}
function MyComponent(){
const [data, setData] = React.useState(null);
React.useEffect(() => {
try {
throw new Error("NETWORK_ERROR");
} catch (e) {
throw e;
}
}, []);
return <div></div>;
}
Vysvětlení:
- Objekt
errorMapukládá informace o chybách, včetně zpráv a příznaků pro opakování, na základě typů nebo kódů chyb. - Funkce
handleCustomErrorzískává podrobnosti o chybě zerrorMapna základě chybové zprávy a vrací výchozí hodnoty, pokud není nalezen žádný specifický kód. - Komponenta
MyErrorBoundarypoužíváhandleCustomErrork získání příslušné chybové zprávy zerrorMap.
Osvědčené postupy pro kategorizaci chyb
- Definujte jasné typy chyb: Stanovte konzistentní sadu typů nebo kódů chyb pro vaši aplikaci.
- Poskytujte kontextové informace: Zahrňte do objektů chyb relevantní detaily pro usnadnění ladění.
- Centralizujte logiku zpracování chyb: Používejte centralizovanou mapu chyb nebo pomocné funkce pro konzistentní správu zpracování chyb.
- Efektivně logujte chyby: Integrujte se se službami pro hlášení chyb, jako jsou Sentry, Rollbar a Bugsnag, pro sledování a analýzu chyb v produkčním prostředí.
- Testujte zpracování chyb: Pište jednotkové testy k ověření, že vaše Error Boundaries správně zpracovávají různé typy chyb.
- Zvažte uživatelský prožitek: Zobrazujte informativní a uživatelsky přívětivé chybové zprávy, které uživatele navedou k řešení. Vyhněte se technickému žargonu.
- Monitorujte chybovost: Sledujte frekvenci různých typů chyb, abyste identifikovali opakující se problémy a prioritizovali jejich opravy.
- Internacionalizace (i18n): Při zobrazování chybových zpráv uživateli se ujistěte, že jsou vaše zprávy správně internacionalizovány pro podporu různých jazyků a kultur. Používejte knihovny jako
i18nextnebo React's Context API pro správu překladů. - Přístupnost (a11y): Ujistěte se, že vaše chybové zprávy jsou přístupné uživatelům se zdravotním postižením. Používejte atributy ARIA pro poskytnutí dalšího kontextu čtečkám obrazovky.
- Bezpečnost: Buďte opatrní, jaké informace zobrazujete v chybových zprávách, zejména v produkčním prostředí. Vyhněte se odhalování citlivých dat, která by mohla být zneužita útočníky. Například nezobrazujte koncovému uživateli surové výpisy zásobníku (stack trace).
Příklad scénáře: Zpracování chyb API v e-commerce aplikaci
Představte si e-commerce aplikaci, která načítá informace o produktech z API. Možné scénáře chyb zahrnují:
- Síťové chyby: API server je nedostupný nebo je přerušeno internetové připojení uživatele.
- Chyby autentizace: Autentizační token uživatele je neplatný nebo vypršel.
- Chyby "zdroj nenalezen": Požadovaný produkt neexistuje.
- Chyby serveru: API server narazil na interní chybu.
Pomocí Error Boundaries a kategorizace chyb může aplikace tyto scénáře elegantně zpracovat:
// Příklad (zjednodušený)
async function fetchProduct(productId) {
try {
const response = await fetch(`/api/products/${productId}`);
if (!response.ok) {
if (response.status === 404) {
throw new Error("PRODUCT_NOT_FOUND");
} else if (response.status === 401 || response.status === 403) {
throw new Error("AUTHENTICATION_ERROR");
} else {
throw new Error("SERVER_ERROR");
}
}
return await response.json();
} catch (error) {
if (error instanceof TypeError && error.message === "Failed to fetch") {
throw new Error("NETWORK_ERROR");
}
throw error;
}
}
class ProductErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, errorDetails: null, errorInfo: null };
}
static getDerivedStateFromError(error) {
const errorDetails = handleCustomError(error.message); // Použijte errorMap, jak bylo ukázáno dříve
return { hasError: true, errorDetails: errorDetails };
}
componentDidCatch(error, errorInfo) {
console.error("Caught error:", error, errorInfo);
this.setState({errorInfo: errorInfo});
}
render() {
if (this.state.hasError) {
const { message, retry } = this.state.errorDetails;
return (
<div>
<h2>Chyba!</h2>
<p>{message}</p>
{retry && <button onClick={() => window.location.reload()}>Zkusit znovu</button>}
</div>
);
}
return this.props.children;
}
}
Vysvětlení:
- Funkce
fetchProductkontroluje stavový kód odpovědi API a na základě stavu vyhazuje specifické typy chyb. - Komponenta
ProductErrorBoundarytyto chyby zachytává a zobrazuje příslušné chybové zprávy. - Pro síťové chyby a chyby serveru se zobrazí tlačítko "Zkusit znovu", které uživateli umožní pokusit se o požadavek znovu.
- V případě chyb autentizace může být uživatel přesměrován na přihlašovací stránku.
- V případě chyby "zdroj nenalezen" se zobrazí zpráva, že produkt neexistuje.
Závěr
Kategorizace chyb v rámci React Error Boundaries je nezbytná pro tvorbu odolných a uživatelsky přívětivých aplikací. Použitím technik, jako jsou kontroly instanceof, chybové kódy a centralizované mapování chyb, můžete efektivně zpracovávat různé scénáře chyb a poskytnout lepší uživatelský prožitek. Nezapomeňte dodržovat osvědčené postupy pro zpracování chyb, logování a testování, abyste zajistili, že vaše aplikace elegantně zvládne neočekávané situace.
Implementací těchto strategií můžete výrazně zlepšit stabilitu a udržovatelnost vašich React aplikací a poskytnout tak plynulejší a spolehlivější zážitek pro vaše uživatele, bez ohledu na jejich polohu nebo původ.
Další zdroje: